using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BanZuiCloudControlAgent.Core.Mqtt.Models;
using BanZuiCloudControlAgent.Utils.Common;
using BanZuiCloudControlAgent.Utils.Database.Repositories;
using BanZuiCloudControlAgent.Utils.Exceptions;
using BanZuiCloudControlAgent.Utils.Logging;

namespace BanZuiCloudControlAgent.Core.Mqtt.Listener
{
    /// <summary>
    /// MQTT消息处理器，负责处理接收到的MQTT消息
    /// </summary>
    public class MqttMessageHandler
    {
        private readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
        private readonly MqttTopics _mqttTopics;
        private readonly MqttMessageRepository _messageRepository;

        /// <summary>
        /// 任务接收事件
        /// </summary>
        public event EventHandler<TaskDispatchEventArgs> TaskReceived;

        /// <summary>
        /// 配置接收事件
        /// </summary>
        public event EventHandler<ConfigEventArgs> ConfigReceived;
        
        /// <summary>
        /// 更新任务接收事件
        /// </summary>
        public event EventHandler<UpdateTaskEventArgs> UpdateTaskReceived;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mqttTopics">MQTT主题</param>
        public MqttMessageHandler(MqttTopics mqttTopics)
        {
            _mqttTopics = mqttTopics ?? throw new ArgumentNullException(nameof(mqttTopics));
            _messageRepository = new MqttMessageRepository();
        }

        /// <summary>
        /// 处理接收到的MQTT消息
        /// </summary>
        /// <param name="topic">主题</param>
        /// <param name="payload">消息内容</param>
        public async void HandleMessage(string topic, string payload)
        {
            try
            {
                _logger.Debug($"处理来自主题 {topic} 的消息");

                // 解析消息类型
                var baseMessage = JsonHelper.Deserialize<BaseMessageModel>(payload);
                if (baseMessage == null)
                {
                    _logger.Warn($"无法解析消息: {payload}");
                    return;
                }
                
                // 保存消息到数据库
                await _messageRepository.SaveMessageAsync(baseMessage);
                
                // 检查消息是否可以处理
                if (!await _messageRepository.CanProcessMessageAsync(baseMessage.MessageId))
                {
                    _logger.Info($"消息不需要处理，跳过: MessageId={baseMessage.MessageId}, MessageType={baseMessage.MessageType}");
                    return;
                }

                // 根据主题和消息类型处理消息
                try
                {
                    if (topic == _mqttTopics.TaskDispatch && baseMessage.MessageType == MessageTypeConstants.TASK_DISPATCH)
                    {
                        await HandleTaskDispatchMessageAsync(payload, baseMessage.MessageId);
                    }
                    else if (topic == _mqttTopics.Config && baseMessage.MessageType == MessageTypeConstants.CONFIG)
                    {
                        await HandleConfigMessageAsync(payload, baseMessage.MessageId);
                    }
                    else if (topic == _mqttTopics.UpdateTask && baseMessage.MessageType == MessageTypeConstants.UPDATE_TASK)
                    {
                        await HandleUpdateTaskMessageAsync(payload, baseMessage.MessageId);
                    }
                    else
                    {
                        _logger.Warn($"未知的主题或消息类型: {topic}, {baseMessage.MessageType}");
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex, $"处理消息失败: {ex.Message}, MessageId={baseMessage.MessageId}, MessageType={baseMessage.MessageType}");
                    
                    // 标记消息为处理失败
                    await _messageRepository.MarkMessageAsFailedAsync(baseMessage.MessageId);
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"处理MQTT消息失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 处理任务下发消息
        /// </summary>
        /// <param name="payload">消息内容</param>
        /// <param name="messageId">消息ID</param>
        private async Task HandleTaskDispatchMessageAsync(string payload, string messageId)
        {
            try
            {
                // 解析任务下发消息
                var taskDispatchModel = JsonHelper.Deserialize<TaskDispatchModel>(payload);
                if (taskDispatchModel == null)
                {
                    _logger.Warn($"无法解析任务下发消息: {payload}");
                    await _messageRepository.MarkMessageAsFailedAsync(messageId);
                    return;
                }

                // 获取任务负载
                TaskDispatchPayloadModel taskPayload = taskDispatchModel.GetPayload();
                if (taskPayload == null)
                {
                    // 尝试将Payload转换为TaskDispatchPayloadModel
                    taskPayload = JsonHelper.Convert<object, TaskDispatchPayloadModel>(taskDispatchModel.Payload);
                    if (taskPayload == null)
                    {
                        _logger.Warn($"无法解析任务负载: {taskDispatchModel.Payload}");
                        await _messageRepository.MarkMessageAsFailedAsync(messageId);
                        return;
                    }
                }

                _logger.Info($"收到任务下发消息，任务ID: {taskPayload.TaskId}, 任务类型: {taskPayload.TaskType}");

                // 触发任务接收事件
                OnTaskReceived(new TaskDispatchEventArgs(taskDispatchModel));
                
                // 标记消息为处理完成
                await _messageRepository.MarkMessageAsCompletedAsync(messageId);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"处理任务下发消息失败: {ex.Message}");
                await _messageRepository.MarkMessageAsFailedAsync(messageId);
                throw;
            }
        }

        /// <summary>
        /// 处理配置消息
        /// </summary>
        /// <param name="payload">消息内容</param>
        /// <param name="messageId">消息ID</param>
        private async Task HandleConfigMessageAsync(string payload, string messageId)
        {
            try
            {
                // 解析配置消息
                var configModel = JsonHelper.Deserialize<ConfigModel>(payload);
                if (configModel == null)
                {
                    _logger.Warn($"无法解析配置消息: {payload}");
                    await _messageRepository.MarkMessageAsFailedAsync(messageId);
                    return;
                }

                // 获取配置负载
                ConfigPayloadModel configPayload = configModel.GetPayload();
                if (configPayload == null)
                {
                    // 尝试将Payload转换为ConfigPayloadModel
                    configPayload = JsonHelper.Convert<object, ConfigPayloadModel>(configModel.Payload);
                    if (configPayload == null)
                    {
                        _logger.Warn($"无法解析配置负载: {configModel.Payload}");
                        await _messageRepository.MarkMessageAsFailedAsync(messageId);
                        return;
                    }
                }

                _logger.Info($"收到配置消息，状态上报间隔: {configPayload.StatusReportInterval}秒");

                // 更新配置
                UpdateConfig(configPayload);

                // 触发配置接收事件
                OnConfigReceived(new ConfigEventArgs(configModel));
                
                // 标记消息为处理完成
                await _messageRepository.MarkMessageAsCompletedAsync(messageId);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"处理配置消息失败: {ex.Message}");
                await _messageRepository.MarkMessageAsFailedAsync(messageId);
                throw;
            }
        }
        
        /// <summary>
        /// 处理更新任务消息
        /// </summary>
        /// <param name="payload">消息内容</param>
        /// <param name="messageId">消息ID</param>
        private async Task HandleUpdateTaskMessageAsync(string payload, string messageId)
        {
            try
            {
                _logger.Info($"收到更新任务原始消息: {payload}");
                
                // 解析更新任务消息
                var updateTaskModel = JsonHelper.Deserialize<UpdateTaskModel>(payload);
                if (updateTaskModel == null)
                {
                    _logger.Warn($"无法解析更新任务消息: {payload}");
                    await _messageRepository.MarkMessageAsFailedAsync(messageId);
                    return;
                }

                _logger.Info($"解析后的更新任务: MessageId={updateTaskModel.MessageId}, MessageType={updateTaskModel.MessageType}, DeviceCode={updateTaskModel.DeviceCode}");
                
                // 获取更新任务负载
                UpdateTaskPayloadModel updateTaskPayload = updateTaskModel.GetPayload();
                if (updateTaskPayload == null)
                {
                    _logger.Warn($"无法解析更新任务负载，原始Payload类型: {updateTaskModel.Payload?.GetType().FullName ?? "null"}");
                    
                    // 尝试将Payload转换为UpdateTaskPayloadModel
                    updateTaskPayload = JsonHelper.Convert<object, UpdateTaskPayloadModel>(updateTaskModel.Payload);
                    if (updateTaskPayload == null)
                    {
                        _logger.Warn($"无法解析更新任务负载: {updateTaskModel.Payload}");
                        await _messageRepository.MarkMessageAsFailedAsync(messageId);
                        return;
                    }
                }

                _logger.Info($"收到更新任务消息，版本: {updateTaskPayload.Version}, 下载链接: {updateTaskPayload.DownloadUrl}, 强制更新: {updateTaskPayload.ForceUpdate}");

                // 触发更新任务接收事件
                OnUpdateTaskReceived(new UpdateTaskEventArgs(updateTaskModel));
                
                // 标记消息为处理完成
                await _messageRepository.MarkMessageAsCompletedAsync(messageId);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"处理更新任务消息失败: {ex.Message}");
                await _messageRepository.MarkMessageAsFailedAsync(messageId);
                throw;
            }
        }

        /// <summary>
        /// 更新配置
        /// </summary>
        /// <param name="configPayload">配置负载</param>
        private void UpdateConfig(ConfigPayloadModel configPayload)
        {
            try
            {
                // 更新心跳间隔
                if (configPayload.StatusReportInterval > 0)
                {
                    ConfigurationManager.SetValue("UI:HeartbeatInterval", configPayload.StatusReportInterval);
                }

                // 更新空闲状态上报间隔
                if (configPayload.IdleStatusReportInterval > 0)
                {
                    ConfigurationManager.SetValue("UI:IdleStatusReportInterval", configPayload.IdleStatusReportInterval);
                }

                // 更新离线阈值
                if (configPayload.OfflineThreshold > 0)
                {
                    ConfigurationManager.SetValue("UI:OfflineThreshold", configPayload.OfflineThreshold);
                }

                // 保存配置
                ConfigurationManager.SaveConfig();

                _logger.Info("已更新配置");
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "更新配置失败");
                throw;
            }
        }

        /// <summary>
        /// 触发任务接收事件
        /// </summary>
        /// <param name="e">事件参数</param>
        protected virtual void OnTaskReceived(TaskDispatchEventArgs e)
        {
            TaskReceived?.Invoke(this, e);
        }

        /// <summary>
        /// 触发配置接收事件
        /// </summary>
        /// <param name="e">事件参数</param>
        protected virtual void OnConfigReceived(ConfigEventArgs e)
        {
            ConfigReceived?.Invoke(this, e);
        }
        
        /// <summary>
        /// 触发更新任务接收事件
        /// </summary>
        /// <param name="e">事件参数</param>
        protected virtual void OnUpdateTaskReceived(UpdateTaskEventArgs e)
        {
            UpdateTaskReceived?.Invoke(this, e);
        }
    }

    /// <summary>
    /// 任务下发事件参数
    /// </summary>
    public class TaskDispatchEventArgs : EventArgs
    {
        /// <summary>
        /// 任务下发消息
        /// </summary>
        public TaskDispatchModel TaskDispatch { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="taskDispatch">任务下发消息</param>
        public TaskDispatchEventArgs(TaskDispatchModel taskDispatch)
        {
            TaskDispatch = taskDispatch;
        }
    }

    /// <summary>
    /// 配置事件参数
    /// </summary>
    public class ConfigEventArgs : EventArgs
    {
        /// <summary>
        /// 配置消息
        /// </summary>
        public ConfigModel Config { get; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="config">配置消息</param>
        public ConfigEventArgs(ConfigModel config)
        {
            Config = config;
        }
    }
} 